﻿using System;
using System.Linq;
using System.Data.Linq;
using System.Collections.Generic;
using System.Text;
using HR.Appointments.Service.Tools;

namespace HR.Appointments.Service.FacadeUsers
{
    /// <summary>
    /// Class for notifiers that uses the system.
    /// </summary>
    public class Notifier
    {
        #region Public Methods
        /// <summary>
        /// Sends notifications to all customers who are confirmed or denied 
        /// and have not received notification
        /// </summary>
        public void SendNotifications(int companyId)
        {
            SendConfirmed(companyId);
            SendDenied(companyId);
        }

        /// <summary>
        /// Send notifications to customers 
        ///  - to confirmed customers who has 1 week or 1 day until booked date.
        ///  - to users who has not confirmed orders by set time or booked time is tommorrow.
        /// </summary>
        public void SendAutomaticNotifications()
        {
            SendBooked();
            SendOrdered();
        }
        #endregion

        #region Private Methods

        private void SendConfirmed(int companyId)
        {
            foreach (OrderEntity order in 
                DAO.Instance.Order.GetUnSentByStatus(companyId, OrderStatus.CONFIRMED))
            {
                SMSGateway.Send(order.Person.Phone, ConfirmedSMSMessage(order));
                EmailGatway.Send(order.Person.Email, ConfirmedEmailMessage(order));

                order.IsSent = true;
                DAO.Instance.Order.Update(order);
            }

        }

        private void SendDenied(int companyId)
        {
            foreach (OrderEntity order in
                DAO.Instance.Order.GetUnSentByStatus(companyId, OrderStatus.DENIED))
            {
                SMSGateway.Send(order.Person.Phone, DeniedSMSMessage(order));
                EmailGatway.Send(order.Person.Email, DeniedEmailMessage(order));

                order.IsSent = true;
                DAO.Instance.Order.Update(order);
            }
        }

        private void SendBooked()
        {
            foreach (OrderEntity order in DAO.Instance.Order.GetNotifiableBooked())
            {
                SMSGateway.Send(order.Person.Phone, BookingSMSMessage(order));
                EmailGatway.Send(order.Person.Email, BookingEmailMessage(order));
            }
        }

        private void SendOrdered()
        {
            foreach (CompanyEntity cmp in DAO.Instance.Company.GetAll())
            {
                var ordered = DAO.Instance.Order.GetNotifiableOrdered(cmp.CompanyId, cmp.DelayTime);
                if (ordered.Count > 0)
                {
                    SMSGateway.Send(cmp.Phone, ConfirmSMSMessage(ordered.Count));
                    EmailGatway.Send(cmp.Email, ConfirmEmailMessage(ordered));
                }
            }
        }

        private string ConfirmedSMSMessage(OrderEntity order)
        {
            System.Diagnostics.Debug.Assert(order.Company != null, "Company is null");
            return string.Format(
                "Tímapöntun var staðfest fyrir {0} á þann {1} kl.{2} hjá {3}. ",
                order.Person.Name,
                order.BookingDate.ToShortDateString(),
                order.FromTime.ToString(),
                order.Company.Name);
        }

        private string ConfirmedEmailMessage(OrderEntity order)
        {
            System.Diagnostics.Debug.Assert(order.Company != null, "Company is null");
            StringBuilder sb = new StringBuilder();
            return string.Format(
                "\nKæri/a {0}\n\n\tTímapöntun var staðfest sem var skráð {1} kl.{2} hjá {3}." +
                "\n\nKveðja,\nTímaskráning.is",
                order.Person.Name,
                order.BookingDate.ToShortDateString(),
                order.FromTime.ToString(),
                order.Company.Name);
        }

        private string DeniedSMSMessage(OrderEntity order)
        {
            System.Diagnostics.Debug.Assert(order.Company != null, "Company is null");
            return string.Format(
                "Tímapöntun var hafnað fyrir {0} á þann {1} kl.{2} hjá {3}. " + 
                "Vinsamlegast pantið annan tíma.",
                order.Person.Name,
                order.BookingDate.ToShortDateString(),
                order.FromTime.ToString(),
                order.Company.Name);
        }

        private string DeniedEmailMessage(OrderEntity order)
        {
            System.Diagnostics.Debug.Assert(order.Company != null, "Company is null");
            StringBuilder sb = new StringBuilder();
            return string.Format(
                "\nKæri/a {0}\n\n\tTímapöntun var hafnað sem var skráð {1} kl.{2} hjá {3}." + 
                "\nVinsamlegast pantið annan tíma." +
                "\n\nKveðja,\nTímaskráning.is",
                order.Person.Name,
                order.BookingDate.ToShortDateString(),
                order.FromTime.ToString(),
                order.Company.Name);
        }

        private string BookingSMSMessage(OrderEntity order)
        {
            System.Diagnostics.Debug.Assert(order.Company != null, "Company is null");
            return string.Format(
                "{0} á pantaðan tíma þann {1} kl.{2} hjá {3}",
                order.Person.Name,
                order.BookingDate.ToShortDateString(),
                order.FromTime.ToString(),
                order.Company.Name);
        }

        private string BookingEmailMessage(OrderEntity order)
        {
            System.Diagnostics.Debug.Assert(order.Company != null, "Company is null");
            StringBuilder sb = new StringBuilder();
            return string.Format(
                "\nKæri/a {0}\n\n\tÞú átt pantaðan tíma þann {1} kl.{2} hjá {3}.\n\nKveðja,\nTímaskráning.is",
                order.Person.Name,
                order.BookingDate.ToShortDateString(),
                order.FromTime.ToString(),
                order.Company.Name);
        }

        private string ConfirmSMSMessage(int orderCount)
        {
            return string.Format(
                "Þú átt eftir að stafesta {0} pantanir.", orderCount);
        }

        private string ConfirmEmailMessage(List<OrderEntity> orders)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("\nÞú átt staðfesta tíma fyrir \n");
            foreach (OrderEntity order in orders)
            {
                sb.Append(string.Format("\t{0} pantað þann {1} kl.{2}\n",
                    order.Person.Name,
                    order.BookingDate.ToShortDateString(),
                    order.FromTime));
            }
            sb.Append("\nKveðja,\nTímaskráning.is");
            return sb.ToString();
        }
        #endregion
    }
}
